package com.ihome.android.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

import com.ihome.android.common.ConfigUtil;

public class FileUtils {
	public static final String	TAG				= FileUtils.class.getSimpleName();
	private static FileUtils	fileUtils		= null;
	public static boolean		SDCardAvailable	= false;

	public static FileUtils getInstance() {
		if (null == fileUtils) {
			fileUtils = new FileUtils();
		}
		return fileUtils;
	}

	public static void LogWrite2SD(Context context, String logContent, String fileName) {
		try {
			File floder = new File(ConfigUtil.LOG_PATH);
			if (!floder.exists()) {
				floder.mkdirs();
			}
			File file = new File(ConfigUtil.LOG_PATH, fileName);
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream outStream = new FileOutputStream(file, true);
			outStream.write(logContent.getBytes());
			outStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void write2Memory(Context context, byte[] b, String filename) {
		FileOutputStream outStream;
		try {
			outStream = context.openFileOutput(filename, Context.MODE_APPEND);
			outStream.write(b);
			outStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void write2Memory(Context context, String logContent, String filename) {

		try {
			File file = new File(ConfigUtil.LOG_PATH + filename);
			if (!file.exists()) {
				file.createNewFile();
			}

			FileOutputStream outStream = new FileOutputStream(file, true);
			outStream.write(logContent.getBytes());
			outStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return
	 */
	public static long getAvailableInternalMemorySize() {
		File path = Environment.getDataDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long availableBlocks = stat.getAvailableBlocks();
		return availableBlocks * blockSize;
	}

	public static List<String> getTempLogFileList(String dir) {
		List<String> filePath = new ArrayList<String>();
		Log.d(TAG, "getFileList dir = " + dir);
		File file = new File(dir);
		if (!file.isDirectory()) {
			Log.d(TAG, "file.mkdirs() = " + file.mkdirs());
		}
		if (file != null) {
			File[] fileList = file.listFiles();
			if (fileList == null) {
				return null;
			}
			for (int i = 0; i < fileList.length; i++) {
				final File f = fileList[i];
				if (f.isFile() && f.getAbsolutePath().contains(Util.getMac()) && !f.getAbsolutePath().contains(".log")) {
					filePath.add(f.getPath());
				}
			}

		}
		return filePath;
	}

	public static List<String> getLogFileList(String dir) {
		List<String> filePath = new ArrayList<String>();
		Log.d(TAG, "getFileList dir = " + dir);
		File file = new File(dir);
		if (!file.isDirectory()) {
			Log.d(TAG, "file.mkdirs() = " + file.mkdirs());
		}
		if (file != null) {
			File[] fileList = file.listFiles();
			if (fileList == null) {
				return null;
			}
			for (int i = 0; i < fileList.length; i++) {
				final File f = fileList[i];
				if (f.isFile() && f.getAbsolutePath().contains(Util.getMac()) && f.getAbsolutePath().contains(".log")) {
					filePath.add(f.getPath());
				}
			}

		}
		return filePath;
	}

	/**
	 * 文件夹遍历 no recursion
	 * 
	 * @param strPath
	 */
	public static LinkedList<File> listLinkedFiles(String strPath) {
		LinkedList<File> list = new LinkedList<File>();
		File dir = new File(strPath);
		File file[] = dir.listFiles();
		for (int i = 0; i < file.length; i++) {
			if (file[i].isDirectory())
				list.add(file[i]);
			else
				Log.d(TAG, "isFile --> " + file[i].getAbsolutePath());
		}
		File tmp;
		while (!list.isEmpty()) {
			tmp = (File) list.removeFirst();
			if (tmp.isDirectory()) {
				file = tmp.listFiles();
				if (file == null)
					continue;
				for (int i = 0; i < file.length; i++) {
					if (file[i].isDirectory())
						list.add(file[i]);
					else
						Log.d(TAG, "isFile --> " + file[i].getAbsolutePath());
				}
			}
			else {
				Log.d(TAG, "isFile --> " + tmp.getAbsolutePath());
			}
		}
		return list;
	}

	// recursion
	public static ArrayList<File> listFiles(String strPath) {
		return refreshFileList(strPath);
	}

	/**
	 * 递归遍历查找文件
	 * 
	 * @param strPath
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static ArrayList<File> refreshFileList(String strPath) {
		ArrayList<File> filelist = new ArrayList<File>();
		File dir = new File(strPath);
		File[] files = dir.listFiles();

		if (files == null)
			return null;
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				refreshFileList(files[i].getAbsolutePath());
			}
			else {
				if (files[i].getName().toLowerCase().endsWith("log"))
					filelist.add(files[i]);
			}
		}
		return filelist;
	}

	public static String readTXTFile(String filePath) {
		String content = "";
		File file = new File(filePath);
		if (file.isDirectory()) {
			Log.d(TAG, "The File doesn't not exist.");
		}
		else {
			try {
				InputStream instream = new FileInputStream(file);
				if (instream != null) {
					InputStreamReader inputreader = new InputStreamReader(instream);
					BufferedReader buffreader = new BufferedReader(inputreader);
					String line;
					while ((line = buffreader.readLine()) != null) {
						content += line + "\n";
					}
					instream.close();
				}
			} catch (java.io.FileNotFoundException e) {
				Log.d(TAG, "The File doesn't not exist.");
			} catch (IOException e) {
				Log.d(TAG, e.getMessage());
			}
		}
		return content;
	}

	/**
	 * 复制单个文件
	 * 
	 * @param oldPath
	 *            String 原文件路径
	 * @param newPath
	 *            String 复制后路径
	 * @return boolean
	 */
	public static boolean copyFile(String oldPath, String newPath) {
		File oldfile = new File(oldPath);
		if (!oldfile.exists()) {
			Log.d(TAG, "copyFile() --> !oldfile.exists() ");
			return false;
		}
		if (!oldfile.isFile()) {
			Log.d(TAG, "copyFile() --> !oldfile.isFile() ");
			return false;
		}
		if (!oldfile.canRead()) {
			Log.d(TAG, "copyFile() --> !oldfile.canRead() ");
			return false;
		}

		boolean isok = false;
		try {
			int bytesum = 0;
			int byteread = 0;
			if (oldfile.exists()) { //文件存在时 
				//读入原文件
				InputStream inStream = new FileInputStream(oldPath);
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1024];
				int length;
				while ((byteread = inStream.read(buffer)) != -1) {
					//字节数 文件大小 
					bytesum += byteread;
					fs.write(buffer, 0, byteread);
				}

				Log.d(TAG, "copyFile() --> bytesum = " + bytesum);
				fs.flush();
				fs.close();
				inStream.close();
				isok = true;
			}
			else {
				isok = false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			isok = false;
		}
		return isok;
	}

	public static void copyfile(File fromFile, File toFile, Boolean rewrite) {
		if (!fromFile.exists()) {
			return;
		}
		if (!fromFile.isFile()) {
			return;
		}
		if (!fromFile.canRead()) {
			return;
		}
		if (!toFile.getParentFile().exists()) {
			toFile.getParentFile().mkdirs();
		}
		if (toFile.exists() && rewrite) {
			toFile.delete();
		}
		//当文件不存时，canWrite一直返回的都是false
		// if (!toFile.canWrite()) {
		// MessageDialog.openError(new Shell(),"错误信息","不能够写将要复制的目标文件" + toFile.getPath());
		// Toast.makeText(this,"不能够写将要复制的目标文件", Toast.LENGTH_SHORT);
		// return ;
		// }
		try {
			java.io.FileInputStream fosfrom = new java.io.FileInputStream(fromFile);
			java.io.FileOutputStream fosto = new FileOutputStream(toFile);
			byte bt[] = new byte[1024];
			int c;
			while ((c = fosfrom.read(bt)) > 0) {
				fosto.write(bt, 0, c); //将内容写到新文件当中
			}
			fosfrom.close();
			fosto.close();
		} catch (Exception ex) {
			Log.e(TAG, ex.getMessage());
		}
	}

	/**
	 * GIF (gif)，文件头：474946 <br>
	 * 
	 * @param filePath
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static boolean isGif(String filePath) {

		try {
			FileInputStream is = new FileInputStream(filePath);
			byte[] b = new byte[3];
			is.read(b, 0, b.length);
			String filehash = bytesToHexString(b);
			Log.d(TAG, "isGif()--> " + filePath + "; filehash =  " + filehash);
			if (filehash.toUpperCase().equals("474946")) {
				return true;
			}
			Log.d(TAG, "isGif()--> " + filePath + " is Error Type");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	/**
	 * JPEG (jpg)，文件头：FFD8FF <br>
	 * PNG (png)，文件头：89504E <br>
	 * Windows Bitmap (bmp)，文件头：424D <br>
	 * 
	 * @param filePath
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static boolean isImg(String filePath) {

		try {
			FileInputStream is = new FileInputStream(filePath);
			byte[] b = new byte[3];
			is.read(b, 0, b.length);
			String filehash = bytesToHexString(b);
			Log.d(TAG, "isImg()--> " + filePath + "; filehash =  " + filehash);
			if (filehash.toUpperCase().equals("89504E") || filehash.toUpperCase().equals("FFD8FF") || filehash.toUpperCase().equals("424D")) {
				return true;
			}
			Log.d(TAG, "isImg()--> " + filePath + " is Error Type");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder();
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
}
